import 'package:baseProjectFlutter/config/app_colors.dart';
import 'package:baseProjectFlutter/widgets_common/image/image_widget.dart';
import 'package:baseProjectFlutter/widgets_common/load_switch/context_data.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

//四种视图状态
enum LoadState { Success, Error, Loading, Empty }

class LoadStateController {
  late _LoadStateLayoutState state;

  void setLoadState(LoadState loadState, {ContextData? contextData}) {
    if (state.setLoadState(loadState)) {
      state.contextData = contextData ?? ContextData();
      state.setState(() {});
    }
  }

  void showLoading({ContextData? contextData}) {
    setLoadState(LoadState.Loading, contextData: contextData);
  }

  void showRetry({ContextData? contextData}) {
    setLoadState(LoadState.Error,
        contextData:
            contextData ?? ContextData(title: "出错啦!!!", buttonText: "点击重试"));
  }

  void showContent({ContextData? contextData}) {
    setLoadState(LoadState.Success, contextData: contextData);
  }

  void showEmpty({ContextData? contextData}) {
    setLoadState(LoadState.Empty,
        contextData: contextData ?? ContextData(title: "什么都没有呢"));
  }

  /// 是否已经与控件绑定
  bool isBind() => this.state != null;

  bool isLoading() => this.state._state == LoadState.Loading;

  //销毁
  void dispose() {
    // this.state = null;
  }
}

//根据不同状态来展示不同的视图
class LoadStateLayout extends StatefulWidget {
  final Widget child; //成功视图
  final Function(ContextData contextData) errorRetry; //错误事件处理
  final Function(ContextData contextData) emptyRetry; //空数据事件处理
  final LoadStateController controller; //状态控制器
  // 如果成功了那么Start方法就不会显示加载中的布局
  bool loadingCanShow = true;

  //标记是否只显示加载中一次
  bool loadingShowOne = true;

  LoadStateLayout({
    super.key,
    required this.controller,
    required this.child,
    required this.errorRetry,
    required this.emptyRetry,
  });

  @override
  _LoadStateLayoutState createState() => _LoadStateLayoutState();
}

class _LoadStateLayoutState extends State<LoadStateLayout> {
  //页面状态
  LoadState _state = LoadState.Success;

  //页面状态
  ContextData contextData = ContextData();

  @override
  void initState() {
    super.initState();
    _bindController();
  }

  bool setLoadState(LoadState value) {
    if (value == LoadState.Loading && !widget.loadingCanShow) {
      return false;
    }
    if (_state != value) {
      _state = value;
      return true;
    }
    return false;
  }

  @override
  void didUpdateWidget(covariant LoadStateLayout oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.controller != widget.controller) {
      _bindController();
    }
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      //宽高都充满屏幕剩余空间
      width: double.infinity,
      height: double.infinity,
      child: _buildWidget,
    );
  }

  void _bindController() {
    widget.controller?.state = this;
  }

  // 根据不同状态来显示不同的视图
  Widget? get _buildWidget {
    switch (_state) {
      case LoadState.Loading:
        return LoadView(contextData);
      case LoadState.Success:
        if (widget.loadingShowOne) {
          widget.loadingCanShow = false;
        }
        return widget.child;
      case LoadState.Error:
        widget.loadingCanShow = true;
        return ErrorView(contextData, widget.errorRetry);
      case LoadState.Empty:
        widget.loadingCanShow = true;
        return NoDataView(contextData, widget.emptyRetry);
      default:
        return null;
    }
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    widget.controller?.dispose();
  }
}

class LoadView extends StatelessWidget {
  ContextData contextData;

  LoadView(this.contextData);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      height: double.infinity,
      alignment: Alignment.center,
      color: Colors.white,
      child: Container(
        alignment: Alignment.center,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            const SizedBox(
              width: 46,
              height: 46,
              child: CircularProgressIndicator(
                valueColor: AlwaysStoppedAnimation(
                    AppColors.load_and_retry_circle_color),
                strokeWidth: 2,
              ),
            ),
            const SizedBox(
              height: 10,
            ),
            Offstage(
              offstage: contextData.title.isEmpty,
              child: Text(
                contextData.title,
                style: const TextStyle(
                    color: AppColors.load_and_retry_load_title_color,
                    fontSize: 12),
              ),
            )
          ],
        ),
      ),
    );
  }
}

class ErrorView extends StatelessWidget {
  Function(ContextData contextData) errorRetry;
  ContextData contextData;

  ErrorView(this.contextData, this.errorRetry);

  @override
  Widget build(BuildContext context) {
    return Container(
        width: double.infinity,
        height: double.infinity,
        color: Colors.white,
        child: InkWell(
          onTap: () {
            errorRetry(contextData);
          },
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Container(
                width: contextData.imgWidth,
                height: contextData.imgHeight,
                child: contextData.resImage.showImage(),
              ),
              Offstage(
                offstage: contextData.title.isEmpty,
                child: Text(
                  contextData.title,
                  style: const TextStyle(
                      color: AppColors.load_and_retry_load_title_color,
                      fontSize: 14),
                ),
              ),
              const SizedBox(height: 15),
              Offstage(
                offstage: contextData.buttonText.isEmpty,
                child: SizedBox(
                  width: 100,
                  height: 32,
                  child: TextButton(
                      onPressed: () {
                        errorRetry(contextData);
                      },
                      style: ButtonStyle(
                        shape: WidgetStateProperty.all<RoundedRectangleBorder>(
                          RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(16.0), // 设置圆角半径
                            side: const BorderSide(
                              color:
                                  AppColors.load_and_retry_button_strokecolor,
                              width: 1,
                            ),
                          ),
                        ),
                      ),
                      child: Text(
                        contextData.buttonText,
                        style: const TextStyle(
                            color: AppColors.load_and_retry_load_title_color,
                            fontSize: 12),
                      )),
                ),
              )
            ],
          ),
        ));
  }
}

class NoDataView extends StatefulWidget {
  final Function(ContextData contextData) emptyRetry; //无数据事件处理
  ContextData contextData;

  NoDataView(this.contextData, this.emptyRetry);

  @override
  _NoDataViewState createState() => _NoDataViewState();
}

class _NoDataViewState extends State<NoDataView> {
  @override
  Widget build(BuildContext context) {
    return Container(
        color: Colors.white,
        width: double.infinity,
        height: double.infinity,
        child: InkWell(
          onTap: () {
            widget.emptyRetry(widget.contextData);
          },
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              SizedBox(
                width: widget.contextData.imgWidth,
                height: widget.contextData.imgHeight,
                child: widget.contextData.resImage.showImage(),
              ),
              Offstage(
                offstage: widget.contextData.title.isEmpty,
                child: Text(
                  widget.contextData.title,
                  style: const TextStyle(
                      color: AppColors.load_and_retry_load_title_color,
                      fontSize: 14),
                ),
              ),
            ],
          ),
        ));
  }
}
